﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Engine.Sgml.Validation.Rules;
using System.Diagnostics;

namespace Engine.Sgml.Configuration {
    /// <summary>
    /// Specifies a set of features to support on SGML validator.
    /// </summary>
    public sealed class ValidatorBehavior {
        internal ValidatorBehavior() {
            }

        /// <summary>
        /// Occurs when a property value changes.
        /// </summary>
        internal event EventHandler<BehaviorChangedEventArgs> Changed;

        private void OnBehaviorChanged(string name) {
            if (Changed != null)
                Changed(this, new BehaviorChangedEventArgs(name));
            }

        /// <summary>
        /// Gets a collection of validation rules.
        /// </summary>
        internal ICollection<IValidationRule> Rules { get; set; }

        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private bool removeIllegalElements;
        /// <summary>
        /// Gets or sets a value indicating whether to remove elements which not defined in DTD schema.
        /// This property has effect if the <see cref="Engine.Sgml.Configuration.ValidatorBehavior.DtdDisabled"/> is set to false;
        /// </summary>
        public bool RemoveIllegalElements {
            get { return removeIllegalElements; }
            set {
                if (removeIllegalElements != value) {
                    removeIllegalElements = value;
                    OnBehaviorChanged("RemoveIllegalElements");
                    }
                }
            }

        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private bool dtdDisabled;
        /// <summary>
        /// Gets or sets a value indicating whether to prohibit validating
        /// the content of document.
        /// </summary>
        /// <value>The DTD schema validation is enabled by default.</value>
        public bool DtdDisabled {
            get { return dtdDisabled; }
            set {
                if (dtdDisabled != value) {
                    dtdDisabled = value;
                    OnBehaviorChanged("DtdDisabled");
                    }
                }
            }

        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private bool ignoreComments;
        /// <summary>
        /// Gets or sets a value indicating whether to ignore comments.
        /// </summary>
        public bool IgnoreComments {
            get { return ignoreComments; }
            set {
                if (ignoreComments != value) {
                    ignoreComments = value;
                    OnBehaviorChanged("IgnoreComments");
                    }
                }
            }

        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private bool preserveDuplicateAttributes;
        /// <summary>
        /// Gets or sets a value indicating whether to preserve duplicate attributes.
        /// </summary>
        /// <value>False by default.</value>
        public bool PreserveDuplicateAttributes {
            get { return preserveDuplicateAttributes; }
            set {
                if (preserveDuplicateAttributes != value) {
                    preserveDuplicateAttributes = value;
                    OnBehaviorChanged("PreserveDuplicateAttributes");
                    }
                }
            }

        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private bool preserveWhiteSpace;
        /// <summary>
        /// Gets or sets a value indicating whether to preserve white space in element content.
        /// </summary>
        /// <remarks>
        /// This property determines how white space is handled during the load and save process.
        /// If PreserveWhitespace is true before <see cref="Engine.Sgml.SgmlDocument.Load(System.Uri)"> Load</see> is called, white space nodes are preserved; otherwise, if this property is false, significant white space is preserved, white space is not.
        /// If PreserveWhitespace is true before Save is called, white space in the document is preserved in the output; otherwise, if this property is false, SgmlDocument auto-indents the output.
        /// </remarks>
        public bool PreserveWhitespace {
            get { return preserveWhiteSpace; }
            set {
                if (preserveWhiteSpace != value) {
                    preserveWhiteSpace = value;
                    OnBehaviorChanged("PreserveWhiteSpace");
                    }
                }
            }

        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private bool caseSensitiveTags;
        /// <summary>
        /// Gets or sets a value indicating whether tags are case sensitive.
        /// </summary>
        /// <remarks>
        /// For instance, element and attribute names are exposed as all uppercase (for consistency) when used on an SGML document, regardless of the character case used in the markup. 
        /// When comparing element or attribute names to strings, the string compare needs to be case insensitive, or the element or attribute name needs to be converted into lowercase before comparing against a lowercase string.
        /// </remarks>
        /// <value>The default value is false.</value>
        public bool CaseSensitiveTags {
            get { return caseSensitiveTags; }
            set {
                if (caseSensitiveTags != value) {
                    caseSensitiveTags = value;
                    OnBehaviorChanged("CaseSensitiveTags");
                    }
                }
            }
        }
    }
